# 统一返回
import _thread
import os
import platform
import random
import uuid
from datetime import datetime, timedelta
from urllib.parse import urlparse
from zz import zz_str, zz_return
import traceback

import dotenv

# 加载配置文件
dotenv.load_dotenv('.env')


def dev_dir():
    """
    开发目录
    """
    script_path = os.path.abspath(__file__)
    return os.path.dirname(os.path.dirname(script_path))


def env(key, def_val=None) -> str:
    """
    获取环境变量
    :param def_val: 默认值
    :param key:
    """
    val = os.getenv(key)
    if val is None:
        return def_val
    return val


# timestamp
def date_timestamp(date=None):
    if date is None:
        date = date_now()
    return int(datetime.timestamp(date))


# timestamp（毫秒）
def date_timestamp_ms(date=None):
    if date is None:
        date = date_now()
    return int(datetime.timestamp(date) * 1000)


# timestamp转datetime
def date_from_timestamp(timestamp) -> datetime:
    return datetime.fromtimestamp(timestamp)


# 加n秒
def date_add_second(date, second) -> datetime:
    return date + timedelta(seconds=second)


# 加n天
def date_add_day(date, day) -> datetime:
    return date + timedelta(days=day)


# 减n天
def date_sub_day(date, day) -> datetime:
    return date - timedelta(days=day)


def date_now() -> datetime:
    return datetime.now()


# 将datetime对象转为字符串，格式为YYYY-MM-DD HH:MM:SS
def date_tostring(date=None, format='%Y-%m-%d %H:%M:%S'):
    if date is None:
        date = date_now()
    return date.strftime(format)


# str转datetime
def date_from_str(s):
    return datetime.fromisoformat(s)


def date_today() -> datetime:
    return date_from_str(date_tostring(format='%Y-%m-%d'))


# 返回当前时间字符串 例：2024-06-18 15:15:48
# 传入 machine.RTC().datetime()
def time_to_string(timestamp):
    return '{0:04d}-{1:02d}-{2:02d} {4:02d}:{5:02d}:{6:02d}'.format(*timestamp)


# 当前时间戳（秒）
def time_diff_ms(begin_ns, end_ns):
    return int((begin_ns - end_ns) / 1000000)


# 开线程
def thread_func(func, *args):
    _thread.start_new_thread(func, args)


# 数组字符串，匹配字符
def arr_find(arr: list, s, match_type=0):
    for i in arr:
        if match_type == 1:
            if zz_str.contains(s, i):
                return True
        else:
            if i == s:
                return True
    return False


# 测试环境
def is_dev():
    is_win = 'win32' in platform.system().lower() or 'windows' in platform.system().lower()
    return is_win


def url_domain(url):
    """
    获取URL域名
    :param url:
    """
    parsed_url = urlparse(url)
    return parsed_url.netloc


def get_uuid(prefix=''):
    id = uuid.uuid1()
    return prefix + str(id).replace("-", "")


def get_id(prefix=''):
    """
    毫秒级ID
    """
    id = date_tostring(None, '%Y%m%d%H%M%S%f')
    return prefix + id


def get_file_content(file_path):
    txt = ""
    try:
        with open(file_path, 'r', encoding='utf-8') as file:
            lines = file.readlines()
            for line in lines:
                txt += line
    except Exception as ex:
        traceback.print_exc()
    return txt


config = None


# 获取配置内容
def config_to_return() -> zz_return.Return:
    """
    配置 转 r
    :return:
    """
    global config
    config_file_path = env("CONFIG_PATH")
    if config is None:
        config = get_file_content(config_file_path)
    return zz_return.parse(config)


def config_get(k):
    """
    获取配置
    :param k:
    """
    r = config_to_return()
    val = r.get_data(k)
    if isinstance(val, str):
        val = val.strip()

    return val


def config_set(k, v):
    """
    保存配置
    :param k:
    :param v:
    """
    global config

    r = config_to_return()
    r.set_data(k, v)
    r.data.pop("errcode")
    r.data.pop("errmsg")
    #
    config_file_path = env("CONFIG_PATH")
    config = r.to_json()
    file = open(config_file_path, "w", encoding="utf-8")
    # 写入数据
    file.write(config)
    # 关闭文件
    file.close()


def num1(num, digits=1):
    """
    数字保留1位小数
    :param num:
    :param digits: 保留x位小数
    """
    x = 1
    for i in range(digits):
        x = x * 10
    return int(num * x) / x


def dict_exists_key(data: dict, k) -> bool:
    """
    key是否存在
    :param data: 对象
    :param k:
    """
    return k in data
